package com.dameng.parallel;

import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 并发造数据
 * 两种方式指定线程数量
 * 1.使用maven：
 * 写一个parallel-suite.xml文件，然后pom.xml文件中添加：
 *     <build>
 *         <plugins>
 *             <plugin>
 *                 <groupId>org.apache.maven.plugins</groupId>
 *                 <artifactId>maven-surefire-plugin</artifactId>
 *                 <version>3.0.0-M7</version>
 *                 <configuration>
 *                     <suiteXmlFiles>
 *                         <suiteXmlFile>src/main/resources/parallel-suite.xml</suiteXmlFile>
 *                     </suiteXmlFiles>
 *                     <threadCount>5</threadCount>
 *                     <parallel>methods</parallel>
 *                 </configuration>
 *             </plugin>
 *         </plugins>
 *     </build>
 * 命令行执行：mvn test
 * 或者（下面的没有尝试，注释pom.xml文件，执行下面的可能也可以）
 * powershell:  mvn test "-DsuiteXmlFile=src/main/resources/parallel-suite.xml"
 * cmd: cmd /c "mvn test -DsuiteXmlFile=src/main/resources/parallel-suite.xml"
 *
 * 2.使用ant
 * 把parallel-suite.xml文件添加在build.xml中
 */

public class DataProvideParallelTest {
    private static final Set<String> threadNames = ConcurrentHashMap.newKeySet();

    /* 1. 并行数据源：parallel = true */
    /**
     * @return
     */
    @DataProvider(name = "para", parallel = true)
    public Object[][] para() {
        // 造 20 条数据，第二维放“编号”即可
        Object[][] data = new Object[20][1];
        for (int i = 0; i < 20; i++) {
            data[i][0] = i;
        }
        return data;
    }

    /* 2. 测试方法：拿到数据就打印线程名 ，默认是10个线程*/

    /**     * 先取 @DataProvider(parallel=true) 的 threadCount（默认 10），若没写再用 suite 的 data-provider-thread-count，最后回落到 10。
     * 本例测试方法仍是单线程顺序执行，只是 数据被并发地喂 进来。想让方法也并行，再加 parallel="methods" 或 parallel="tests"。
     * @param no
     * @throws InterruptedException
     *
     * 控制@DataProvider并行度：使用 @DataProvider(parallel = true) + testng.xml配置
     *
     * 推荐组合：@DataProvider(parallel = true) + testng.xml中的 thread-count
     */
    @Test(dataProvider = "para")
    public void test(int no) throws InterruptedException {
        String threadName = Thread.currentThread().getName();
        threadNames.add(threadName);

        // 模拟一点业务耗时，让线程交错更明显
        Thread.sleep(300);
        System.out.printf("数据 %2d 被线程 %s 执行%n",
                no, Thread.currentThread().getName());
        Assert.assertTrue(true);
    }

    @AfterClass
    public void displayThreadStatistics() {
        System.out.println("\n" + "=".repeat(50));
        System.out.println("并发执行统计:");
        System.out.println("总测试用例数: 20");
        System.out.println("使用的线程数量: " + threadNames.size());
        System.out.println("线程列表: " + threadNames);
        System.out.println("=".repeat(50));
    }

}
